/** @file Sequence.cc
 * Implementation of class Sequence.
 */
#include <iostream>
#include <sys/wait.h>		// for: wait(), WIF...(status)
#include <cstring>			// for: strsignal()
#include "asserts.h"
#include "unix_error.h"
#include "Sequence.h"
#include "unistd.h"

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

using namespace std;


void  Sequence::addPipeline(Pipeline *pp)
{
	require(pp != 0);
	commands.push_back(pp);
}


Sequence::~Sequence()
{
	for (vector<Pipeline*>::iterator  i = commands.begin() ; i != commands.end() ; ++i)
		delete  *i;
}


bool	Sequence::isEmpty()	const
{
	return commands.empty();
}


void signal_callback_handler(int sig)
{
	cerr << "Caught signal %d\n" << sig << endl;
	switch(sig){
		case SIGINT :
				cerr <<	strsignal(sig) << endl; // print error message
				 exit(sig);
			break;
		case SIGQUIT:
				cerr <<	strsignal(sig) << endl; // print error message
			 	 exit(sig);
			break;
	}

}


// TODO:	Lookout somewhere for special commands such as 'exit',
//			'logout', 'cd', etc, which may have to be
//			done by the shell itself.


// Execute the pipelines in this sequence one by one
void	Sequence::execute()
{
	//cerr << "Sequence::execute\n";//DEBUG
	int status;

	signal(SIGINT, SIG_IGN); // If the disposition is set to SIG_IGN, then the signal is ignored.
	signal(SIGQUIT, SIG_IGN); //

	// Execute each pipeline in turn.
	// Also see: fork(2), nice(2), wait(2), WIF...(2), strsignal(3)
	size_t  j = commands.size();	// for count-down
	for (vector<Pipeline*>::iterator  i = commands.begin() ; i != commands.end() ; ++i, --j)
	{
		Pipeline  *pp = *i;
		if (!pp->isEmpty())
		{

			switch (fork())
			{
			case 0:

					if(pp->isBackground()){
						nice(5); // pas de prioriteit van backgroudn process aan.
					}
					else
					{
						signal(SIGINT,signal_callback_handler);
						signal(SIGQUIT,signal_callback_handler);
					}

						pp->execute();

				break;
			case -1:
				throw unix_error("fork");
				break;
			default:
				//geen background process
				if(!pp->isBackground()){

						wait(&status);

						if( WIFSIGNALED( status ) )
						{
							cerr << "Pipe closed by singal:" << strsignal(status) << endl;
						}

				}

				break;

			}
		}
		// else ignore empty pipeline
	}
}




// vim:ai:aw:ts=4:sw=4:

